package com.example.springboottools.utils.staples.test;

import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;

public class FileObjectUtils {
    public static byte[] getFileBytes(String serverUrl) throws Exception {
        return getFileBytes(serverUrl,true);
    }
    public static byte[] getFileBytes(String serverUrl, boolean urlEncode) throws Exception {

        InputStream inputStream = getFileInputStream(serverUrl,urlEncode);
        if(inputStream == null ) return null;

        int len = 0;
        byte [] buffer = new byte[1024 * 2];
        ByteArrayOutputStream output = new ByteArrayOutputStream();

        while((len = inputStream.read(buffer)) != -1){
            output.write(buffer,0,len);
        }

        byte [] bytes = output.toByteArray();
        inputStream.close();
        output.close();

        return bytes;
    }

    private static String cleanDiagonal(String serverUrl){
        serverUrl = serverUrl.replaceAll("//","/").replaceAll(":/","://");
        if(serverUrl.lastIndexOf("/") == serverUrl.length() - 1) serverUrl = serverUrl.substring(0,serverUrl.length() - 1);
        return serverUrl;
    }
    private static String getUrlEncode(String str){
        if(str == null) return null;
        try {
            return URLEncoder.encode(str,"UTF-8").replaceAll("\\+","%20")
                    .replaceAll("%3D","=")
                    .replaceAll("%3F","?")
                    .replaceAll("%26","&");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return str;
    }
    public static InputStream getFileInputStream(String serverUrl, boolean urlEncode){
        InputStream inputStream = null;
        try{
            // 清除多余斜杆
            serverUrl = cleanDiagonal(serverUrl);
            // 文件名 URL编码
            if(urlEncode){
                int index = serverUrl.lastIndexOf("/") + 1;
                serverUrl = serverUrl.substring(0,index) + getUrlEncode(serverUrl.substring(index,serverUrl.length()));
            }

            URL url = new URL(serverUrl);
            // 判断使用协议
            if("https".equalsIgnoreCase(url.getProtocol())){
                // https协议
                // jdk1.7 默认使用SSL TLSv1版本，会报：javax.net.ssl.SSLException: Received fatal alert: protocol_version异常
                // 这里需要更改SSL版本
                HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();
                SSLContext sc = SSLContext.getInstance("TLSv1.2");
                sc.init(null, new TrustManager[] { new MyX509TrustManager() }, new java.security.SecureRandom());
                connection.setSSLSocketFactory(sc.getSocketFactory());

                // 设置传输形式
                connection.setRequestMethod("GET");
                // 添加请求头
                connection.setRequestProperty("Connection", "Keep-Alive");
                connection.setRequestProperty("Charset", "UTF-8");

                // 403、404 说明文件不存在，返回空
                int responseCode = connection.getResponseCode();
                if(responseCode == 403 || responseCode == 404) return null;

                // 得到文件流
                inputStream = connection.getInputStream();

            }else{
                // http协议
                HttpURLConnection connection = (HttpURLConnection) url.openConnection();
                // 设置传输形式
                connection.setRequestMethod("GET");
                // 添加请求头
                connection.setRequestProperty("Connection", "Keep-Alive");
                connection.setRequestProperty("Charset", "UTF-8");

                // 403、404 说明文件不存在，返回空
                int responseCode = connection.getResponseCode();
                if(responseCode == 403 || responseCode == 404) return null;

                // 得到文件流
                inputStream = connection.getInputStream();
            }

        }catch (Exception e){
            String method = Thread.currentThread().getStackTrace()[1].getMethodName(); // 方法名
           // logger.error( method + "方法，调用【文件存储系统】异常：",e);
        }finally {
            if(inputStream == null){
                //logger.error("【文件存储系统】请求失败参数：" + serverUrl);
            }
        }

        return inputStream;
    }

    static class MyX509TrustManager implements X509TrustManager {

        @Override
        public void checkClientTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {

        }

        @Override
        public void checkServerTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {

        }

        @Override
        public X509Certificate[] getAcceptedIssuers() {
            return new X509Certificate[0];
        }
    }
}
